package com.gc.jbnfgen.gen;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author dmitry.mamonov
 */
public abstract class JBNF {
    private String name;
    private boolean printed;
    private LinkedHashMap<String,JBNF> nested = new LinkedHashMap<String,JBNF>();

    public JBNF(String name) {
        this.name = name;
    }

    public JBNF add(JBNF jbnf) {
        return add(jbnf.getName(),jbnf);
    }

    public JBNF add(String alias,JBNF jbnf) {
        nested.put(alias,jbnf);
        return this;
    }

    public JBNF addRecursive() {
        return addRecursive(getName());
    }

    public JBNF addRecursive(String alias) {
        return add(alias, this);
    }

    protected void setPrinted(boolean printed) {
        this.printed = printed;
    }

    public String getName() {
        return name;
    }

    public String getTypeName(){
        return StringUtils.capitalize(getName());
    }

    public String getFieldName(){
        return StringUtils.uncapitalize(getName());
    }


    protected Map<String,JBNF> getNested() {
        return nested;
    }

    protected boolean isPrinted() {
        return printed;
    }

    public JBNF reset(){
        resetImpl(new HashSet<JBNF>());
        return this;
    }

    private void resetImpl(Set<JBNF> alrady){
        if (alrady.contains(this)==false){
            setPrinted(false);
            alrady.add(this);
            for(JBNF sub:nested.values()){
                sub.resetImpl(alrady);
            }
        }
    }
}
